package cn.lingyangwl.agile.pay.common.utils;

import cn.lingyangwl.agile.infra.InfraApi;
import cn.lingyangwl.agile.pay.common.constants.Cs;
import cn.lingyangwl.framework.tool.core.exception.BizException;
import cn.hutool.core.io.FileUtil;
import cn.hutool.http.HttpUtil;
import cn.lingyangwl.agile.infra.module.file.constants.FileCons;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;

/**
 * 支付平台 获取系统文件工具类
 *
 * @author shenguangyang
 */
@Component
public class ChannelCertConfigKitBean {

    @Resource
    private InfraApi infraApi;


    public String getCertFilePath(String certFilePath) {
        return getCertFile(certFilePath).getAbsolutePath();
    }

    public File getCertFile(String certFilePath) {
        File certFile = new File(Cs.CERT_FILE_BASE_PATH + "/" + certFilePath.replace(FileCons.UPLOAD_BASE_URL, ""));

        if (certFile.exists()) { // 本地存在直接返回
            return certFile;
        }


        // 已经向oss请求并且返回了空文件时
        if (new File(certFile.getAbsolutePath() + ".notexists").exists()) {
            return certFile;
        }

        // 当文件夹不存在时， 需要创建。
        if (!certFile.getParentFile().exists()) {
            certFile.getParentFile().mkdirs();
        }

        // 请求下载并返回 新File
        return downloadFile(certFilePath, certFile);
    }


    /**
     * 下载文件
     */
    private synchronized File downloadFile(String dbCertFilePath, File certFile) {
        // 请求文件并写入
        String fileUrl = infraApi.getFileIntranetUrl(dbCertFilePath);
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        HttpUtil.download(fileUrl, os, true);

        File file = new File(certFile.getAbsolutePath());
        FileUtil.writeFromStream(new ByteArrayInputStream(os.toByteArray()), file, true);

        // 下载失败， 写入.notexists文件， 避免那下次再次下载影响效率。
        try {
            if (!new File(certFile.getAbsolutePath() + ".notexists").createNewFile()) {
                throw new BizException("文件下载失败");
            }
        } catch (IOException e) {
            throw new BizException("文件下载失败");
        }

        return file;
    }

}
